home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PLAYymate for OS/2
/
Playmate for OS2.iso
/
p4os2026
/
life2.c
next >
Wrap
Text File
|
1993-09-05
|
29KB
|
774 lines
/*------------------------------------------------*/
/* LIFE2.C -- John Conway's game of life. */
/* */
/* Program from charles Petzold's */
/* book with minor enhancements */
/* by Larry Nomer */
/* */
/*------------------------------------------------*/
#define INCL_BASE
#include "life2.h"
CHAR szClientClass [] = "Life" ;
HAB hab ;
static HINI hini ;
static HWND hwndFrame, hwndClient ;
static ULONG ulFColor ;
static ULONG ulBColor ;
static SHORT sCellScale ;
int main( void )
{
static ULONG flFrameFlags = FCF_TITLEBAR |
FCF_SYSMENU |
FCF_SIZEBORDER |
FCF_SHELLPOSITION |
FCF_MINMAX |
FCF_TASKLIST |
FCF_MENU |
FCF_ICON ;
SWP swp ; // Used to query window position.
ULONG ulSize;
LONG wx, wy, wcx, wcy;
HMQ hmq ;
RECTL rectlDesktop ;
QMSG qmsg ;
hab = WinInitialize ( 0 ) ;
hmq = WinCreateMsgQueue ( hab, 0 ) ;
WinRegisterClass( hab, szClientClass, ClientWndProc,
CS_SIZEREDRAW, 0 ) ;
hwndFrame = WinCreateStdWindow ( HWND_DESKTOP, 0L, /* Usu WS_VISIBLE here */
&flFrameFlags, szClientClass, NULL,
0L, 0UL, ID_RESOURCE, &hwndClient );
/**************************************************************************/
/* */
/* The entire SWP (Window Position) data structure should be in the INI */
/* file, so it is retrieved if possible. If not, default size and */
/* position is relative to the size of the desktop, and centred. */
/* */
/**************************************************************************/
ulSize = sizeof (SWP);
if (PrfQueryProfileData (HINI_PROFILE, szAppName, szKeyPos,
&swp, &ulSize))
{
wx = swp.x;
wy = swp.y;
wcx = swp.cx;
wcy = swp.cy;
}
else
{
WinQueryWindowRect (HWND_DESKTOP, &rectlDesktop);
wx = rectlDesktop.xRight / 8;
wy = rectlDesktop.yTop / 8;
wcx = rectlDesktop.xRight * 3 / 4;
wcy = rectlDesktop.yTop * 3 / 4;
}
WinSetWindowPos (hwndFrame, HWND_TOP,
wx, wy, wcx, wcy,
SWP_SHOW |
SWP_SIZE |
SWP_MOVE |
SWP_ACTIVATE) ;
WinShowWindow ( hwndFrame, TRUE ) ; /* Now make window visible. */
WinSetWindowText (hwndFrame, "Life2 - v1.0") ;
while (WinGetMsg( hab, &qmsg, 0UL, 0, 0) )
WinDispatchMsg( hab, &qmsg ) ;
WinDestroyWindow( hwndFrame ); /* Destroy window parentage */
WinDestroyMsgQueue( hmq ); /* Cut phone line */
WinTerminate( hab ); /* Release remaining resources */
DosExit( EXIT_PROCESS, 0 ); /* Exit OS/2 process orderly */
}
VOID EnableMenuItem ( HWND hwndMenu, SHORT idMenuItem, BOOL fEnable )
{
WinSendMsg ( hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT ( idMenuItem, TRUE ) ,
MPFROM2SHORT ( MIA_DISABLED, fEnable ? 0 : MIA_DISABLED ) ) ;
}
VOID ErrorMsg ( HWND hwnd, CHAR *szMessage )
{
WinMessageBox ( HWND_DESKTOP, hwnd, szMessage, szClientClass, 0,
MB_OK | MB_ICONEXCLAMATION ) ;
}
BOOL CreateLogicalColorTable( HPS hps )
{
#define NALTABLEI 32L
BOOL fRet ;
static LONG alTable[NALTABLEI] =
{ 0L, 0x00000000L /* (0) black (RGB_BLACK) */
, 1L, 0x000000A0L /* (1) dark blue */
, 2L, 0x0000A000L /* (2) dark green */
, 3L, 0x0000A0A0L /* (3) dark cyan */
, 4L, 0x00A00000L /* (4) dark red */
, 5L, 0x00900090L /* (5) dark pink */
, 6L, 0x00505000L /* (6) brown */
, 7L, 0x00D0D0D0L /* (7) pale gray */
, 8L, 0x00505050L /* (8) dark gray */
, 9L, 0x000000FFL /* (9) blue (RGB_BLUE) */
, 10L, 0x0000FF00L /* (A) green (RGB_GREEN) */
, 11L, 0x0000DDDDL /* (B) cyan (RGB_CYAN) */
, 12L, 0x00EE0000L /* (C) red (RGB_RED) */
, 13L, 0x00FF00FFL /* (D) pink (RGB_PINK) */
, 14L, 0x00FFFF00L /* (E) yellow (RGB_YELLOW) */
, 15L, 0x00FFFFFFL /* (F) white (RGB_WHITE) */
} ;
fRet = GpiCreateLogColorTable( hps /* PS handle */
, LCOL_PURECOLOR /* reset current color table */
, LCOLF_INDRGB /* in RBG format */
, 0L /* start index */
, NALTABLEI /* number of table entries */
, alTable /* RGB color table array */
) ;
return(fRet) ;
}
VOID DrawCell ( HPS hps, SHORT x, SHORT y, SHORT cxCell, SHORT cyCell,
BYTE bCell, ULONG ulFColor, ULONG ulBColor )
{
RECTL rcl ;
rcl.xLeft = x * cxCell ;
rcl.yBottom = y * cyCell ;
rcl.xRight = rcl.xLeft + cxCell - 1 ;
rcl.yTop = rcl.yBottom + cyCell - 1 ;
WinFillRect ( hps, &rcl, bCell & 1 ? ulFColor : ulBColor ) ;
}
VOID DoGeneration ( HPS hps, PBYTE pbGrid, SHORT xNumCells, SHORT yNumCells,
SHORT cxCell, SHORT cyCell,
ULONG ulFColor, ULONG ulBColor )
{
SHORT x, y, sSum ;
for ( y = 0 ; y < yNumCells ; y++ )
for ( x = 0 ; x < xNumCells ; x++ )
{
// *** Lower left corner ***
if ( ( x == 0 ) && ( y == 0 ) ) // We're just starting.
{
// *** Examine cells we haven't visited yet.
sSum = *(pbGrid + 1 ) + // Right
*(pbGrid + xNumCells + 1 ) + // Upper Right
*(pbGrid +(xNumCells*y) + 1 ) + // Lower Right
*(pbGrid +(xNumCells*y) ) + // Lower
*(pbGrid +(xNumCells*(y+1)) - 1 ) + // Lower Left!
*(pbGrid + xNumCells - 1 ) + // Left
*(pbGrid + xNumCells ) + // Upper
*(pbGrid + (2*xNumCells) - 1 ) ; // Upper Left
}
else
// *** Upper left corner ***
if ( ( x == 0 ) && ( y == yNumCells - 1 ) )
{
// *** Cells we have visited.
sSum = (*(pbGrid - xNumCells ) + // Lower
*(pbGrid - 1 ) + // Lower Left
*(pbGrid-(xNumCells*y) ) + // Upper
*(pbGrid-(xNumCells*y) + 1 ) + // Upper Right
*((pbGrid-(xNumCells*(y-1))) - 1 ) + // Upper Left
*((pbGrid - xNumCells) + 1 ) ) // Lower Right
>> 4 ;
// *** Now examine cells we haven't visited yet.
sSum += *(pbGrid + 1 ) + // Right
*(pbGrid + xNumCells - 1 ) ; // Left
}
else
// *** Lower right corner ***
if ( ( y == 0 ) && ( x == xNumCells - 1 ) )
{
// *** Cells we have visited.
sSum = (*(pbGrid - 1) ) // Left
>> 4 ;
// *** Examine cells we haven't visited yet.
sSum += *((pbGrid - xNumCells) + 1 ) + // Right
*(pbGrid + 1 ) + // Upper Right
*(pbGrid +(xNumCells*(y-1) ) + 1 ) + // Lower Right
*(pbGrid +(xNumCells*y ) ) + // Lower
*((pbGrid +(xNumCells*y ) ) - 1 ) + // Lower Left
*(pbGrid + xNumCells ) + // Upper
*((pbGrid + xNumCells ) - 1 ) ; // Upper Left
}
else
// *** Upper right corner ***
if ( ( y == yNumCells - 1 ) && ( x == xNumCells - 1 ) )
{
// *** Cells we have visited (done all but current in this case).
sSum = (*(pbGrid - xNumCells ) + // Lower
*((pbGrid - xNumCells) - 1 ) + // Lower Left
*(pbGrid-(xNumCells*y) ) + // Upper
*((pbGrid-(xNumCells*(y+1))) + 1 ) + // Upper Right
*((pbGrid-xNumCells*y) - 1 ) + // Upper Left
*((pbGrid-xNumCells) + 1 ) + // Right
*(pbGrid - 1 ) + // Left
*((pbGrid-2*xNumCells) + 1 ) ) // Lower Right
>> 4 ;
}
else
// *** Bottom edge ***
if ( y == 0 )
{
// *** Cells we have visited.
sSum = (*(pbGrid - 1) ) // Left
>> 4 ;
// *** Examine cells we haven't visited yet.
sSum += *(pbGrid + 1) + // Right
*(pbGrid + xNumCells + 1) + // Upper Right
*(pbGrid + xNumCells*(yNumCells-1) + 1) + // Lower Right
*(pbGrid + xNumCells*(yNumCells-1) ) + // Lower
*((pbGrid + xNumCells*(yNumCells-1))- 1) + // Lower Left
*(pbGrid + xNumCells ) + // Upper
*((pbGrid + xNumCells) - 1) ; // Upper Left
}
else
// *** Top edge ***
if ( y == yNumCells - 1 )
{
// *** Cells we have visited.
sSum = (*(pbGrid - xNumCells ) + // Lower
*((pbGrid - xNumCells) - 1 ) + // Lower Left
*(pbGrid - 1 ) + // Left
*( pbGrid-(xNumCells*y) ) + // Upper
*((pbGrid-(xNumCells*y)) + 1 ) + // Upper Right
*((pbGrid-(xNumCells*y)) - 1 ) + // Upper Left
*((pbGrid - xNumCells) + 1 ) ) // Lower Right
>> 4 ;
// *** Examine cells we haven't visited yet.
sSum += *(pbGrid + 1 ) ; // Right
}
else
// *** Left edge ***
if ( x == 0 )
{
// *** When x == 0, we haven't done the LEFT cell because it
// *** wraps to the right side of the grid.
sSum = (*(pbGrid - xNumCells ) + // Lower
*(pbGrid - 1) + // Lower Left
*((pbGrid - xNumCells) + 1)) // Lower Right
>> 4 ;
// *** Now examine cells we haven't visited yet.
sSum += *(pbGrid + 1) + // Right
*(pbGrid + xNumCells + 1) + // Upper Right
*(pbGrid + xNumCells - 1) + // Left (Not done yet)
*(pbGrid + xNumCells ) + // Upper
*(pbGrid + (2*xNumCells) - 1) ; // Upper Left
}
else
// *** Right Edge ***
if ( x == xNumCells - 1 )
{
// "Been visited group does not usually include RIGHT! This
// is another special effect of the grid wrap around.
sSum = (*(pbGrid - 1 ) + // Left
*((pbGrid - xNumCells) - 1 ) + // Lower Left
*( pbGrid - xNumCells ) + // Lower
*((pbGrid - xNumCells) + 1 ) + // Right
*((pbGrid - (2*xNumCells)) + 1)) // Lower Right
>> 4 ;
sSum += *( pbGrid + 1) + // Upper Right
*( pbGrid + xNumCells ) + // Upper
*( pbGrid + xNumCells - 1) ; // Upper Left
}
// *** Normal case (not on any edges or corners of grid). ***
else
{
// *** Get shifted info from cells we have already done.
sSum = (*(pbGrid - 1) + // Left
*((pbGrid - xNumCells) - 1) + // Lower Left
*(pbGrid - xNumCells ) + // Lower
*((pbGrid - xNumCells) + 1)) // Lower Right
>> 4 ;
// *** and now from those not yet processed.
sSum += *(pbGrid + 1) + // Right
*(pbGrid + xNumCells + 1) + // Upper Right
*(pbGrid + xNumCells ) + // Upper
*(pbGrid + xNumCells - 1) ; // Upper Left
}
sSum = ( sSum | *pbGrid ) & 0x0F ;
*pbGrid <<= 4 ;
if ( sSum == 3 )
*pbGrid |= 1 ;
if (( *pbGrid & 1) != *pbGrid >> 4 )
DrawCell ( hps, x, y, cxCell, cyCell, *pbGrid,
ulFColor, ulBColor ) ;
pbGrid++ ;
}
}
VOID DisplayGenerationNum ( HPS hps, SHORT xGen, SHORT yGen, LONG lGeneration)
{
static CHAR szBuffer [24] = "Generation " ;
POINTL ptl;
ptl.x = xGen ;
ptl.y = yGen ;
_ltoa ( lGeneration, szBuffer + 11, 10 ) ;
GpiSavePS ( hps ) ;
GpiSetBackMix ( hps, BM_OVERPAINT ) ;
GpiCharStringAt ( hps, &ptl, (LONG) strlen (szBuffer), szBuffer ) ;
GpiRestorePS ( hps, -1L ) ;
}
MRESULT EXPENTRY ClientWndProc ( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
{
static BOOL fTimerGoing ;
static HWND hwndMenu ;
static LONG lGeneration ;
static PBYTE pbBaseGrid ;
static PBYTE pbGrid ;
static SHORT cxChar, cyChar, cyDesc, cxClient, cyClient, xGenNum, yGenNum,
cxCell, cyCell, xNumCells, yNumCells ;
static APIRET rc ;
static ULONG ulTotCells ;
static ULONG RanPct ;
static SHORT cmd ;
static BOOL fButton1Down, fButton2Down ;
HSAVEWP hsvwp ;
SWP aswp[COUNT] ;
static BOOL ctRet ;
POINTL ptlPointerPos ;
FONTMETRICS fm ;
HPS hps ;
POINTL ptl ;
SHORT x, y ;
switch ( msg )
{
case WM_CREATE:
{
TWOCOLORS tc ;
SCALE sc ;
ULONG ulSizeTC ;
ULONG ulSizeSC ;
hps = WinGetPS ( hwnd ) ;
GpiQueryFontMetrics ( hps, (LONG) sizeof fm, &fm ) ;
cxChar = (SHORT) fm.lAveCharWidth ;
cyChar = (SHORT) fm.lMaxBaselineExt ;
cyDesc = (SHORT) fm.lMaxDescender ;
WinReleasePS ( hps ) ;
fButton1Down = fButton2Down = 0 ;
ulSizeTC = sizeof(TWOCOLORS) ;
ulSizeSC = sizeof(SCALE) ;
hwndMenu = WinWindowFromID (
WinQueryWindow( hwnd, QW_PARENT ),
FID_MENU ) ;
if (PrfQueryProfileData (HINI_PROFILE, szAppName, szKeyColor,
&tc, &ulSizeTC ))
{
ulFColor = tc.colorF ;
ulBColor = tc.colorB ;
}
else
{
ulFColor = 2L ;
ulBColor = 7L ;
}
if (PrfQueryProfileData (HINI_PROFILE, szAppName, szKeyScale,
&sc, &ulSizeSC ))
{
sCellScale = sc.cScale ;
}
else
{
sCellScale = 2 ;
}
WinSendMsg ( hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT ( sCellScale, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, MIA_CHECKED ) ) ;
return 0 ;
}
case WM_SIZE:
if (pbBaseGrid)
{
DosFreeMem ( pbBaseGrid ) ;
pbBaseGrid = 0 ;
}
if ( fTimerGoing )
{
WinStopTimer (hab, hwnd, ID_TIMER ) ;
fTimerGoing = FALSE ;
}
cxClient = SHORT1FROMMP ( mp2 ) ;
cyClient = SHORT2FROMMP ( mp2 ) ;
xGenNum = cxChar ;
yGenNum = cyClient - cyChar + cyDesc ;
cxCell = cxChar * 2 / sCellScale ;
cyCell = cyChar / sCellScale ;
xNumCells = cxClient / cxCell ;
yNumCells = ( cyClient - cyChar ) / cyCell ;
if ((xNumCells <= 0) || (yNumCells <= 0 ))
{
ErrorMsg ( hwnd, "Not enough room for even one cell." ) ;
}
else if ( (LONG) xNumCells * yNumCells > 65536L )
{
ErrorMsg ( hwnd, "More than 64K cells not supported." ) ;
}
else
{
ulTotCells = xNumCells * yNumCells ;
rc = DosAllocMem ( (PVOID *) &pbBaseGrid, ulTotCells,
PAG_COMMIT | PAG_WRITE | PAG_READ ) ;
if ( rc != 0 )
{
ErrorMsg ( hwnd, "Not enough memory for this many cells." ) ;
pbBaseGrid = 0 ;
return 0 ;
}
}
pbGrid = pbBaseGrid ;
for ( y = 0 ; y < yNumCells ; y++ )
for ( x = 0 ; x < xNumCells ; x++ )
*pbGrid++ = 0 ;
WinEnableMenuItem ( hwndMenu, IDM_SIZE, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_START, pbBaseGrid != 0 ) ;
WinEnableMenuItem ( hwndMenu, IDM_STOP, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_STEP, pbBaseGrid != 0 ) ;
WinEnableMenuItem ( hwndMenu, IDM_CLEAR, pbBaseGrid != 0 ) ;
WinEnableMenuItem ( hwndMenu, IDM_RANDOM, pbBaseGrid != 0 ) ;
lGeneration = 0 ;
return 0 ;
case WM_MOUSEMOVE:
WinQueryPointerPos ( HWND_DESKTOP, &ptlPointerPos ) ;
WinMapWindowPoints ( HWND_DESKTOP, hwnd, &ptlPointerPos, 1 ) ;
x = ptlPointerPos.x / cxCell ;
y = ptlPointerPos.y / cyCell ;
if ( ( fButton1Down || fButton2Down ) &&
pbBaseGrid &&
!fTimerGoing &&
x < xNumCells &&
y < yNumCells )
{
pbGrid = pbBaseGrid ;
hps = WinGetPS ( hwnd ) ;
ctRet = CreateLogicalColorTable( hps ) ;
if ( fButton1Down )
DrawCell ( hps, x, y, cxCell, cyCell,
( *( pbGrid + y * xNumCells + x ) |= 1 ),
ulFColor, ulBColor ) ;
else if ( fButton2Down )
DrawCell ( hps, x, y, cxCell, cyCell,
( *( pbGrid + y * xNumCells + x ) &= 0 ),
ulFColor, ulBColor ) ;
WinReleasePS ( hps ) ;
}
break ;
case WM_BUTTON1UP:
fButton1Down = 0 ;
break ;
case WM_BUTTON2UP:
fButton2Down = 0 ;
break ;
case WM_BUTTON1DOWN:
fButton1Down = 1 ;
break ;
case WM_BUTTON2DOWN:
fButton2Down = 1 ;
break ;
case WM_COMMAND:
cmd = SHORT1FROMMP( mp1 );
switch( cmd )
{
case IDM_LARGE:
case IDM_SMALL:
case IDM_TINY:
{
SCALE sc ;
WinSendMsg ( hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT ( sCellScale, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, 0 ) ) ;
sCellScale = cmd ;
WinSendMsg ( hwndMenu, MM_SETITEMATTR,
MPFROM2SHORT ( sCellScale, TRUE ),
MPFROM2SHORT ( MIA_CHECKED, MIA_CHECKED ) ) ;
WinSendMsg ( hwnd, WM_SIZE, NULL,
MPFROM2SHORT ( cxClient, cyClient ) ) ;
WinInvalidateRect ( hwnd, NULL, FALSE ) ;
sc.cScale = sCellScale ;
PrfWriteProfileData (HINI_PROFILE, szAppName, szKeyScale,
&sc, sizeof (SCALE) );
return 0 ;
}
case IDM_START:
if ( !WinStartTimer ( hab, hwnd, ID_TIMER, 1 ) )
{
ErrorMsg ( hwnd, "Too many clocks or timers." ) ;
}
else
{
fTimerGoing = TRUE ;
WinEnableMenuItem ( hwndMenu, IDM_SIZE, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_START, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_STOP, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_STEP, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_CLEAR, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_RANDOM, FALSE ) ;
}
return 0 ;
case IDM_STOP:
WinStopTimer ( hab, hwnd, ID_TIMER ) ;
fTimerGoing = FALSE ;
WinEnableMenuItem ( hwndMenu, IDM_SIZE, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_START, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_STOP, FALSE ) ;
WinEnableMenuItem ( hwndMenu, IDM_STEP, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_CLEAR, TRUE ) ;
WinEnableMenuItem ( hwndMenu, IDM_RANDOM, TRUE ) ;
return 0 ;
case IDM_STEP:
WinSendMsg ( hwnd, WM_TIMER, NULL, NULL ) ;
return 0 ;
case IDM_CLEAR:
lGeneration = 0L ;
pbGrid = pbBaseGrid ;
for ( y = 0 ; y < yNumCells ; y++ )
for ( x = 0 ; x < xNumCells ; x++ )
*pbGrid++ = 0 ;
WinInvalidateRect ( hwnd, NULL, FALSE ) ;
return 0 ;
case IDM_RAN100:
case IDM_RAN90:
case IDM_RAN80:
case IDM_RAN70:
case IDM_RAN60:
case IDM_RAN50:
case IDM_RAN40:
case IDM_RAN30:
case IDM_RAN20:
case IDM_RAN10:
RanPct = ( cmd - 100 ) ;
lGeneration = 0L ;
pbGrid = pbBaseGrid ;
for ( y = 0 ; y < yNumCells ; y++ )
for ( x = 0 ; x < xNumCells ; x++ )
*pbGrid++ = ( ( rand() < ( RAND_MAX * RanPct ) / 100 ) &&
( x >= RAN_BORDER ) &&
( x < ( xNumCells - RAN_BORDER ) ) &&
( y >= RAN_BORDER ) &&
( y < ( yNumCells - RAN_BORDER ) ) ) ;
WinInvalidateRect ( hwnd, NULL, FALSE ) ;
return 0 ;
case FCLR_BLACK:
case FCLR_DARKBLUE:
case FCLR_DARKGREEN:
case FCLR_DARKCYAN:
case FCLR_DARKRED:
case FCLR_DARKPINK:
case FCLR_BROWN:
case FCLR_PALEGRAY:
case FCLR_DARKGRAY:
case FCLR_WHITE:
case FCLR_BLUE:
case FCLR_RED:
case FCLR_GREEN:
case FCLR_CYAN:
case FCLR_PINK:
case FCLR_YELLOW:
{
TWOCOLORS tc ;
ulFColor = 100-cmd;
tc.colorF = ulFColor ;
tc.colorB = ulBColor ;
WinInvalidateRect( hwnd, (PRECTL)NULL, FALSE );
PrfWriteProfileData (HINI_PROFILE, szAppName, szKeyColor,
&tc, sizeof (TWOCOLORS) );
}
break;
case BCLR_BLACK:
case BCLR_DARKBLUE:
case BCLR_DARKGREEN:
case BCLR_DARKCYAN:
case BCLR_DARKRED:
case BCLR_DARKPINK:
case BCLR_BROWN:
case BCLR_PALEGRAY:
case BCLR_DARKGRAY:
case BCLR_WHITE:
case BCLR_BLUE:
case BCLR_RED:
case BCLR_GREEN:
case BCLR_CYAN:
case BCLR_PINK:
case BCLR_YELLOW:
{
TWOCOLORS tc ;
WinInvalidateRect( hwnd, (PRECTL)NULL, FALSE );
ulBColor = 300-cmd;
tc.colorF = ulFColor ;
tc.colorB = ulBColor ;
PrfWriteProfileData (HINI_PROFILE, szAppName, szKeyColor,
&tc, sizeof (TWOCOLORS) );
}
break;
}
break;
case WM_TIMER:
hps = WinGetPS ( hwnd ) ;
ctRet = CreateLogicalColorTable( hps ) ;
DisplayGenerationNum ( hps, xGenNum, yGenNum, ++lGeneration ) ;
pbGrid = pbBaseGrid ;
DoGeneration ( hps, pbGrid, xNumCells, yNumCells, cxCell, cyCell,
ulFColor, ulBColor ) ;
WinReleasePS ( hps ) ;
return 0 ;
case WM_PAINT:
hps = WinBeginPaint ( hwnd, NULLHANDLE, NULL ) ;
ctRet = CreateLogicalColorTable( hps ) ;
GpiErase ( hps ) ;
if ( pbBaseGrid )
{
for ( x = 1 ; x <= xNumCells ; x++ )
{
ptl.x = cxCell * x - 1 ;
ptl.y = 0 ;
GpiMove ( hps, &ptl ) ;
ptl.y = cyCell * yNumCells - 1 ;
GpiLine ( hps, &ptl ) ;
}
for ( y = 1 ; y <= yNumCells ; y++ )
{
ptl.x = 0 ;
ptl.y = cyCell * y - 1 ;
GpiMove ( hps, &ptl ) ;
ptl.x = cxCell * xNumCells - 1 ;
GpiLine ( hps, &ptl ) ;
}
/* if ( *pbGrid++ ) */
pbGrid = ( PBYTE ) pbBaseGrid ;
for ( y = 0 ; y < yNumCells ; y++ )
for ( x = 0 ; x < xNumCells ; x++ )
{
pbGrid++ ;
DrawCell ( hps, x, y, cxCell, cyCell,
*( pbGrid - 1 ),
ulFColor, ulBColor ) ;
}
DisplayGenerationNum ( hps, xGenNum, yGenNum, lGeneration ) ;
}
WinEndPaint ( hps ) ;
return 0 ;
case WM_DESTROY:
if ( fTimerGoing )
WinStopTimer ( hab, hwnd, ID_TIMER ) ;
if ( pbBaseGrid )
DosFreeMem ( pbBaseGrid ) ;
return 0 ;
case WM_SAVEAPPLICATION:
/**********************************************************************/
/* */
/* The notice to save to INI-profiles. Save current window size and */
/* position; also save current selections of value-sets. */
/* */
/**********************************************************************/
{
SWP swp;
WinQueryWindowPos (WinQueryWindow (hwnd, QW_PARENT), &swp);
PrfWriteProfileData (HINI_PROFILE, szAppName, szKeyPos,
&swp, sizeof (SWP));
}
break;
}
return WinDefWindowProc ( hwnd, msg, mp1, mp2 ) ;
}